package com.xidian.zhiancloud.service.emergencyManagement;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xidian.zhiancloud.dao.*;
import com.xidian.zhiancloud.dao.DrillDivisionOfTasksMapper;
import com.xidian.zhiancloud.dao.syset.SysUserMapper;
import com.xidian.zhiancloud.dao.syset.usermanage.OrganizationMapper;
import com.xidian.zhiancloud.dto.emergencyManagement.EmergencyDrillRecordDTO;
import com.xidian.zhiancloud.dto.emergencyManagement.EmergencyPlanManagementDTO;
import com.xidian.zhiancloud.enums.GeneralResponseEnums;
import com.xidian.zhiancloud.exception.CustomizeException;
import com.xidian.zhiancloud.model.*;
import com.xidian.zhiancloud.model.syset.Organization;
import com.xidian.zhiancloud.model.syset.SysPosition;
import com.xidian.zhiancloud.model.syset.SysUser;
import com.xidian.zhiancloud.qo.emergencyManagement.EmergencyDrillRecordQO;
import com.xidian.zhiancloud.qo.emergencyManagement.EmergencyMaterialsInventoryManagementQO;
import com.xidian.zhiancloud.vo.emergencyManagement.EmergencyDrillRecordVO;
import com.xidian.zhiancloud.vo.emergencyManagement.EmergencyMaterialsInventoryManagementVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class EmergencyDrillRecordService extends ServiceImpl<EmergencyDrillRecordMapper, EmergencyDrillRecord> implements IService<EmergencyDrillRecord> {
    @Autowired
    private EmergencyDrillRecordMapper emergencyDrillRecordMapper;

    @Autowired
    private DrillDivisionOfTasksMapper drillDivisionOfTasksMapper;

    @Autowired
    private EmergencyPlanManagementMapper emergencyPlanManagementMapper;

    @Autowired
    private OrganizationMapper organizationMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private EmergencyDrillPlanMapper emergencyDrillPlanMapper;

    @Autowired
    private EmergencyDivisionOfTasksMapper emergencyDivisionOfTasksMapper;

    @Transactional(rollbackFor = {RuntimeException.class, Error.class, CustomizeException.class})
    public Boolean add(EmergencyDrillRecord emergencyDrillRecord) {
        int result = emergencyDrillRecordMapper.insert(emergencyDrillRecord);
        if (result == 0) {//不关联
            throw new CustomizeException(GeneralResponseEnums.SYSTEM_ERROR);
        }
        int connection = emergencyDrillRecord.getConnectionId();
        if (connection == 0) {
            Long planEmergeId = emergencyDrillRecord.getPlanEmergeNameId();
            if (planEmergeId == null) {
                throw new CustomizeException(GeneralResponseEnums.SYSTEM_ERROR);
            }
            EmergencyPlanManagement emergencyPlanManagement = emergencyPlanManagementMapper.selectById(planEmergeId);
            emergencyDrillRecord.setTypePId(emergencyPlanManagement.getTypeId());
//            if(emergencyDrillRecord.getNumP()==null){
//                emergencyDrillRecord.setNumP(0);
//            }
//            if(emergencyDrillRecord.getRecord()==null){
//                emergencyDrillRecord.setRecord("暂无记录");
//            }
//            if(emergencyDrillRecord.getQuestion()==null){
//                emergencyDrillRecord.setQuestion("暂无");
//            }
            int i = emergencyDrillRecordMapper.updateById(emergencyDrillRecord);
            return i == 1;
        } else if (connection == 1) {
            Long planId = emergencyDrillRecord.getDrillPlanId();
            EmergencyDrillPlan emergencyDrillPlan = emergencyDrillPlanMapper.selectById(planId);
            emergencyDrillRecord.setPlanEmergeNameId(emergencyDrillPlan.getNameRId());
            emergencyDrillRecord.setTypePId(emergencyDrillPlan.getTypeRId());
            emergencyDrillRecord.setTypeId(emergencyDrillPlan.getTypeId());
            emergencyDrillRecord.setOrganizationId(emergencyDrillPlan.getOrganizationId());
            //emergencyDrillRecord.setLocale(emergencyDrillPlan.getLocale());
            //emergencyDrillRecord.setStartTime(emergencyDrillPlan.getStartTime());
            //emergencyDrillRecord.setEndTime(emergencyDrillPlan.getEndTime());
//            if(emergencyDrillRecord.getNumP()==null){
//                emergencyDrillRecord.setNumP(0);
//            }
//            if(emergencyDrillRecord.getRecord()==null){
//                emergencyDrillRecord.setRecord("暂无记录");
//            }
//            if(emergencyDrillRecord.getQuestion()==null){
//                emergencyDrillRecord.setQuestion("暂无");
//            }
            int i = emergencyDrillRecordMapper.updateById(emergencyDrillRecord);
            return i == 1;
        }
        return true;
//        EmergencyDrillRecord emergencyDrillRecord = emergencyDrillRecordDTO.getEmergencyDrillRecord();
//        int result = emergencyDrillRecordMapper.insert(emergencyDrillRecord);
//        if (result == 0) {
//            throw new CustomizeException(GeneralResponseEnums.SYSTEM_ERROR);
//        }
//        for(DrillDivisionOfTasks drillDivisionOfTasks: emergencyDrillRecordDTO.getDrillDivisionOfTasksList()){
//            drillDivisionOfTasks.setEmergencyDrillId(emergencyDrillRecordDTO.getEmergencyDrillRecord().getId());
//            int tmp = drillDivisionOfTasksMapper.insert(drillDivisionOfTasks);
//            if(tmp==0){
//                throw new CustomizeException(GeneralResponseEnums.SYSTEM_ERROR);
//            }
//        }
    }

    public EmergencyDrillRecordVO getById(Long id) {
        EmergencyDrillRecord emergencyDrillRecord = emergencyDrillRecordMapper.selectById(id);
        if (emergencyDrillRecord == null) {
            throw new CustomizeException(GeneralResponseEnums.SYSTEM_ERROR);
        }
        EmergencyDrillRecordVO vo = new EmergencyDrillRecordVO();
        BeanUtils.copyProperties(emergencyDrillRecord, vo);
        int connection = emergencyDrillRecord.getConnectionId();
        if (connection == 0) {
            EmergencyPlanManagement emergencyPlanManagement = emergencyPlanManagementMapper.selectById(vo.getPlanEmergeNameId());
            vo.setPlanEmergeName(emergencyPlanManagement == null ? "该演练预案不存在" : emergencyPlanManagement.getName());
        } else if (connection == 1) {

            EmergencyDrillPlan emergencyDrillPlan = emergencyDrillPlanMapper.selectById(vo.getDrillPlanId());
            vo.setDrillPlanName(emergencyDrillPlan == null ? "该演练计划不存在" : emergencyDrillPlan.getName());
            Organization organization = organizationMapper.selectById(emergencyDrillPlan.getOrganizationId());
            vo.setOrganizationName(organization == null ? "该部门不存在" : organization.getName());
        }
        return vo;
//        //修改为mybatis plus的条件查询
//        DrillDivisionOfTasksExample drillDivisionOfTasksExample = new DrillDivisionOfTasksExample();
//        drillDivisionOfTasksExample.createCriteria().andEmergencyDrillIdEqualTo(id);
//        List<DrillDivisionOfTasks> drillDivisionOfTasksList= drillDivisionOfTasksMapper.selectByExample(drillDivisionOfTasksExample);
//        EmergencyDrillRecordDTO emergencyDrillRecordDTO = new EmergencyDrillRecordDTO();
//        emergencyDrillRecordDTO.setEmergencyDrillRecord(emergencyDrillRecord);
//        emergencyDrillRecordDTO.setDrillDivisionOfTasksList(drillDivisionOfTasksList);
//        return emergencyDrillRecordDTO;
    }


    @Transactional(rollbackFor = {RuntimeException.class, Error.class, CustomizeException.class})
    public Boolean deleteByIds(Long[] ids) {
        int res = 0;
        for (int i = 0; i < ids.length; i++) {
            res += emergencyDrillRecordMapper.deleteById(ids[i]);
        }
        if (res == 0) {
            return false;
        }
        return true;
    }

    @Transactional(rollbackFor = {RuntimeException.class, Error.class, CustomizeException.class})
    public Boolean patchById(EmergencyDrillRecord emergencyDrillRecord) {
        int result = emergencyDrillRecordMapper.updateById(emergencyDrillRecord);
        if (result == 0) {
            throw new CustomizeException(GeneralResponseEnums.SYSTEM_ERROR);
        }
        int connection = emergencyDrillRecord.getConnectionId();
        if (connection == 0) {
            Long planEmergeId = emergencyDrillRecord.getPlanEmergeNameId();
            EmergencyPlanManagement emergencyPlanManagement = emergencyPlanManagementMapper.selectById(planEmergeId);
            emergencyDrillRecord.setTypePId(emergencyPlanManagement.getTypeId());
        } else if (connection == 1) {
            Long planId = emergencyDrillRecord.getDrillPlanId();
            EmergencyDrillPlan emergencyDrillPlan = emergencyDrillPlanMapper.selectById(planId);
            emergencyDrillRecord.setPlanEmergeNameId(emergencyDrillPlan.getNameRId());
            emergencyDrillRecord.setTypePId(emergencyDrillPlan.getTypeRId());
            emergencyDrillRecord.setTypeId(emergencyDrillPlan.getTypeId());
            emergencyDrillRecord.setOrganizationId(emergencyDrillPlan.getOrganizationId());
            emergencyDrillRecord.setLocale(emergencyDrillPlan.getLocale());
            emergencyDrillRecord.setStartTime(emergencyDrillPlan.getStartTime());
            emergencyDrillRecord.setEndTime(emergencyDrillPlan.getEndTime());
        }
        return true;
    }

    public IPage<EmergencyDrillRecordVO> getListByQO(EmergencyDrillRecordQO emergencyDrillRecordQO) {
        Page<EmergencyDrillRecordVO> page = new Page<>(emergencyDrillRecordQO.getCurrent(), emergencyDrillRecordQO.getSize());
        OrderItem orderItem = new OrderItem();
        orderItem.setColumn("create_time").setAsc(false);
        page.getOrders().add(orderItem);
        IPage<EmergencyDrillRecordVO> ans = emergencyDrillRecordMapper.getListByQO(page, emergencyDrillRecordQO);
        for (EmergencyDrillRecordVO record : ans.getRecords()) {
            int connection = record.getConnectionId();
            if (connection == 0) {
                EmergencyPlanManagement emergencyPlanManagement = emergencyPlanManagementMapper.selectById(record.getPlanEmergeNameId());
                record.setPlanEmergeName(emergencyPlanManagement == null ? "该演练预案不存在" : emergencyPlanManagement.getName());
            } else if (connection == 1) {

                EmergencyDrillPlan emergencyDrillPlan = emergencyDrillPlanMapper.selectById(record.getDrillPlanId());
                record.setDrillPlanName(emergencyDrillPlan == null ? "该演练计划不存在" : emergencyDrillPlan.getName());
                Organization organization = organizationMapper.selectById(record.getOrganizationId());
                record.setOrganizationName(organization == null ? "该部门不存在" : organization.getName());
            }
        }
        return ans;
    }


    public Map<Byte, Integer> type2(Long id, Date startTime, Date endTime, Long companyId) {
        Map<Byte, Integer> ans = new HashMap<>();
        List<EmergencyDrillRecord> list = null;

        if (id == null) {
            LambdaQueryWrapper<EmergencyDrillRecord> query = Wrappers.<EmergencyDrillRecord>lambdaQuery();
            query.eq(EmergencyDrillRecord::getCompanyId, companyId);
            list = emergencyDrillRecordMapper.selectList(query);
        } else {
            LambdaQueryWrapper<EmergencyDrillRecord> query = Wrappers.<EmergencyDrillRecord>lambdaQuery();
            query.eq(id != null, EmergencyDrillRecord::getOrganizationId, id)
                    .eq(companyId != null, EmergencyDrillRecord::getCompanyId, companyId)
                    .between(startTime != null && endTime != null, EmergencyDrillRecord::getCreateTime, startTime, endTime);

            Queue<Long> queue = new LinkedList<>();
            List<Long> ids = new LinkedList<>();
            ids.add(id);
            queue.add(id);
            while (!queue.isEmpty()) {
                Long front = queue.poll();
                LambdaQueryWrapper<Organization> queryorg = Wrappers.<Organization>lambdaQuery();
                queryorg.eq(Organization::getPid, front);
                List<Organization> tmp = organizationMapper.selectList(queryorg);
                for (Organization organization : tmp) {
                    ids.add(organization.getId());
                    queue.add(organization.getId());
                }
            }

            query.in(EmergencyDrillRecord::getId, ids);
            list = emergencyDrillRecordMapper.selectList(query);
        }


        if (list == null) {
            return ans;
        } else {
            for (EmergencyDrillRecord emergencyDrillRecord : list) {
                if (!ans.containsKey(emergencyDrillRecord.getTypeId())) {
                    ans.put(emergencyDrillRecord.getTypeId(), 1);
                } else {
                    ans.put(emergencyDrillRecord.getTypeId(), ans.get(emergencyDrillRecord.getTypeId()) + 1);
                }
            }
        }
        return ans;
    }

    public Map<String, Integer> type3(Date startTime, Date endTime, Long companyId) {
        Map<String, Integer> ans = new HashMap<>();
        List<EmergencyDrillRecord> list = null;

        LambdaQueryWrapper<EmergencyDrillRecord> query = Wrappers.<EmergencyDrillRecord>lambdaQuery();
        query.eq(companyId != null, EmergencyDrillRecord::getCompanyId, companyId)
                .between(startTime != null && endTime != null, EmergencyDrillRecord::getCreateTime, startTime, endTime);
        list = emergencyDrillRecordMapper.selectList(query);
        if (list == null) {
            return ans;
        } else {
            for (EmergencyDrillRecord emergencyDrillRecord : list) {
                Organization organization = organizationMapper.selectById(emergencyDrillRecord.getOrganizationId());
                if (organization == null) {
                    continue;
                }
                String name = organization.getName();
                if (!ans.containsKey(name)) {
                    ans.put(name, 1);
                } else {
                    ans.put(name, ans.get(name) + 1);
                }
            }
        }
        return ans;
    }

}
